//! DSL集成测试
//! 
//! 测试DSL解析器、模板引擎、变量系统和函数系统的集成功能

use ai_test_platform::dsl::{
    DSLParser, TemplateEngine, VariableManager, FunctionRegistry,
    TestCaseDefinition, ConfigDefinition, StepDefinition,
};
use serde_json::Value;

#[tokio::test]
async fn test_complete_dsl_workflow() {
    // 1. 创建DSL解析器
    let parser = DSLParser::new();
    
    // 2. 解析YAML测试用例
    let yaml_content = r#"
config:
  name: "用户API测试"
  base_url: "https://api.example.com"
  variables:
    user_id: 123
    token: "abc123"
    api_version: "v1"

teststeps:
  - name: "获取用户信息"
    variables:
      endpoint: "/users/${user_id}"
    request:
      method: "GET"
      url: "${base_url}/${api_version}${endpoint}"
      headers:
        Authorization: "Bearer ${token}"
        Content-Type: "application/json"
    extract:
      username: "body.name"
      email: "body.email"
    validate:
      - check: "status_code"
        expect: 200
      - check: "json_path"
        path: "body.id"
        expect: "${user_id}"

  - name: "更新用户信息"
    request:
      method: "PUT"
      url: "${base_url}/${api_version}/users/${user_id}"
      headers:
        Authorization: "Bearer ${token}"
        Content-Type: "application/json"
      json:
        name: "${concat(username, \"_updated\")}"
        email: "${email}"
        timestamp: "${timestamp()}"
    validate:
      - check: "status_code"
        expect: 200
"#;

    // 3. 解析测试用例定义
    let definition = parser.parse_yaml(yaml_content).expect("解析YAML失败");
    
    // 4. 验证解析结果
    assert_eq!(definition.config.name, "用户API测试");
    assert_eq!(definition.config.base_url, Some("https://api.example.com".to_string()));
    assert_eq!(definition.teststeps.len(), 2);
    
    // 5. 创建变量管理器并设置变量
    let mut var_manager = VariableManager::new();
    
    // 设置全局变量（从config）
    if let Some(variables) = &definition.config.variables {
        var_manager.set_global_variables(variables.clone());
    }
    
    // 设置基础URL
    if let Some(base_url) = &definition.config.base_url {
        var_manager.set_global_variable("base_url".to_string(), Value::String(base_url.clone()));
    }
    
    // 6. 创建模板引擎
    let mut template_engine = TemplateEngine::new();
    
    // 7. 处理第一个步骤
    let step1 = &definition.teststeps[0];
    
    // 设置步骤变量（先解析步骤变量中的模板）
    if let Some(step_vars) = &step1.variables {
        let mut resolved_step_vars = std::collections::HashMap::new();
        for (key, value) in step_vars {
            let resolved_value = template_engine.resolve_value(value, &mut var_manager)
                .expect("解析步骤变量失败");
            resolved_step_vars.insert(key.clone(), resolved_value);
        }
        var_manager.set_step_variables(resolved_step_vars);
    }
    
    // 解析请求URL
    if let Some(request) = &step1.request {
        let resolved_request = template_engine.resolve_value(request, &mut var_manager)
            .expect("解析请求失败");
        
        // 验证URL解析
        let expected_url = "https://api.example.com/v1/users/123";
        let actual_url = resolved_request["url"].as_str().unwrap();
        println!("期望URL: {}", expected_url);
        println!("实际URL: {}", actual_url);
        assert_eq!(actual_url, expected_url);
        
        // 验证头部解析
        let auth_header = resolved_request["headers"]["Authorization"].as_str().unwrap();
        assert_eq!(auth_header, "Bearer abc123");
    }
    
    // 8. 模拟提取变量（通常从HTTP响应中提取）
    var_manager.set_session_variable("username".to_string(), Value::String("john_doe".to_string()));
    var_manager.set_session_variable("email".to_string(), Value::String("john@example.com".to_string()));
    
    // 清除步骤变量，准备处理下一个步骤
    var_manager.clear_step_variables();
    
    // 9. 处理第二个步骤
    let step2 = &definition.teststeps[1];
    
    if let Some(request) = &step2.request {
        let resolved_request = template_engine.resolve_value(request, &mut var_manager)
            .expect("解析第二个请求失败");
        
        // 验证URL解析
        let expected_url = "https://api.example.com/v1/users/123";
        assert_eq!(resolved_request["url"].as_str().unwrap(), expected_url);
        
        // 验证JSON体中的函数调用
        let json_body = &resolved_request["json"];
        let name_field = json_body["name"].as_str().unwrap();
        assert_eq!(name_field, "john_doe_updated"); // concat函数结果
        
        let email_field = json_body["email"].as_str().unwrap();
        assert_eq!(email_field, "john@example.com");
        
        // 验证时间戳函数调用
        assert!(json_body["timestamp"].is_number());
    }
    
    println!("✅ DSL集成测试通过！");
}

#[tokio::test]
async fn test_function_system_integration() {
    let mut var_manager = VariableManager::new();
    let mut template_engine = TemplateEngine::new();
    
    // 设置测试变量
    var_manager.set_global_variable("base".to_string(), Value::String("hello".to_string()));
    var_manager.set_global_variable("num1".to_string(), Value::Number(10.into()));
    var_manager.set_global_variable("num2".to_string(), Value::Number(20.into()));
    
    // 测试字符串函数
    let template1 = "${upper(${base})}";
    let result1 = template_engine.resolve_string(template1, &mut var_manager).unwrap();
    assert_eq!(result1, "HELLO");
    
    // 测试数学函数
    let template2 = "${sum(${num1}, ${num2})}";
    let result2 = template_engine.resolve_string(template2, &mut var_manager).unwrap();
    assert_eq!(result2, "30");
    
    // 测试随机函数
    let template3 = "${random_int(1, 100)}";
    let result3 = template_engine.resolve_string(template3, &mut var_manager).unwrap();
    let random_num: i32 = result3.parse().unwrap();
    assert!(random_num >= 1 && random_num <= 100);
    
    // 测试UUID函数
    let template4 = "${uuid()}";
    let result4 = template_engine.resolve_string(template4, &mut var_manager).unwrap();
    assert_eq!(result4.len(), 36); // UUID长度
    assert!(result4.contains('-')); // UUID格式
    
    println!("✅ 函数系统集成测试通过！");
}

#[tokio::test]
async fn test_variable_scope_resolution() {
    let mut var_manager = VariableManager::new();
    let mut template_engine = TemplateEngine::new();
    
    // 设置不同作用域的同名变量
    var_manager.set_global_variable("name".to_string(), Value::String("global_name".to_string()));
    var_manager.set_session_variable("name".to_string(), Value::String("session_name".to_string()));
    var_manager.set_step_variable("name".to_string(), Value::String("step_name".to_string()));
    
    // 测试变量优先级：step > session > global
    let template = "Hello ${name}";
    let result = template_engine.resolve_string(template, &mut var_manager).unwrap();
    assert_eq!(result, "Hello step_name");
    
    // 清除步骤变量，测试session优先级
    var_manager.clear_step_variables();
    let result2 = template_engine.resolve_string(template, &mut var_manager).unwrap();
    assert_eq!(result2, "Hello session_name");
    
    // 清除会话变量，测试global优先级
    var_manager.clear_session_variables();
    let result3 = template_engine.resolve_string(template, &mut var_manager).unwrap();
    assert_eq!(result3, "Hello global_name");
    
    println!("✅ 变量作用域解析测试通过！");
}

#[tokio::test]
async fn test_json_parsing_and_resolution() {
    let parser = DSLParser::new();
    
    // 测试JSON格式的测试用例
    let json_content = r#"
{
  "config": {
    "name": "JSON测试用例",
    "base_url": "https://api.test.com",
    "variables": {
      "api_key": "test_key_123",
      "timeout": 30
    }
  },
  "teststeps": [
    {
      "name": "JSON请求测试",
      "request": {
        "method": "POST",
        "url": "${base_url}/api/test",
        "headers": {
          "X-API-Key": "${api_key}"
        },
        "json": {
          "timeout": "${timeout}",
          "timestamp": "${timestamp()}"
        }
      }
    }
  ]
}
"#;

    let definition = parser.parse_json(json_content).expect("解析JSON失败");
    assert_eq!(definition.config.name, "JSON测试用例");
    assert_eq!(definition.teststeps.len(), 1);
    
    // 验证变量解析
    let mut var_manager = VariableManager::new();
    if let Some(variables) = &definition.config.variables {
        var_manager.set_global_variables(variables.clone());
    }
    if let Some(base_url) = &definition.config.base_url {
        var_manager.set_global_variable("base_url".to_string(), Value::String(base_url.clone()));
    }
    
    let mut template_engine = TemplateEngine::new();
    let step = &definition.teststeps[0];

    if let Some(request) = &step.request {
        let resolved = template_engine.resolve_value(request, &mut var_manager).unwrap();
        
        assert_eq!(resolved["url"].as_str().unwrap(), "https://api.test.com/api/test");
        assert_eq!(resolved["headers"]["X-API-Key"].as_str().unwrap(), "test_key_123");
        assert_eq!(resolved["json"]["timeout"], Value::Number(30.into()));
        assert!(resolved["json"]["timestamp"].is_number());
    }
    
    println!("✅ JSON解析和解析测试通过！");
}

#[tokio::test]
async fn test_enhanced_dsl_features() {
    let parser = DSLParser::new();

    // 测试带有条件执行、循环和重试的复杂测试用例
    let yaml_content = r#"
config:
  name: "增强DSL功能测试"
  base_url: "https://api.example.com"
  variables:
    user_id: 123
    enabled: true
    retry_count: 3
  parameters:
    - user_type: "admin"
      permissions: ["read", "write", "delete"]
    - user_type: "user"
      permissions: ["read"]
  tags: ["api", "user", "enhanced"]
  priority: 1
  parallel:
    enabled: true
    max_workers: 2

teststeps:
  - name: "条件执行测试"
    if_condition: "${enabled}"
    request:
      method: "GET"
      url: "${base_url}/status"
    validate:
      - check: "status_code"
        expect: 200

  - name: "跳过的步骤"
    skip: true
    request:
      method: "GET"
      url: "${base_url}/skip"

  - name: "重试配置测试"
    retry:
      max_attempts: 3
      delay_ms: 1000
      multiplier: 2.0
      max_delay_ms: 5000
      retry_on:
        - type: "status_code"
          status_codes: [500, 502, 503]
        - type: "timeout"
    request:
      method: "POST"
      url: "${base_url}/retry-test"
    timeout: 10

  - name: "循环测试"
    loop_config:
      loop_type: "data"
      data: [1, 2, 3]
      variable: "item"
      max_iterations: 10
    request:
      method: "GET"
      url: "${base_url}/items/${item}"
"#;

    // 解析测试用例
    let definition = parser.parse_yaml(yaml_content).expect("解析增强YAML失败");

    // 验证基本结构
    assert_eq!(definition.config.name, "增强DSL功能测试");
    assert_eq!(definition.config.tags, Some(vec!["api".to_string(), "user".to_string(), "enhanced".to_string()]));
    assert_eq!(definition.config.priority, Some(1));
    assert!(definition.config.parallel.is_some());
    assert_eq!(definition.config.parameters.as_ref().unwrap().len(), 2);

    // 验证并行配置
    let parallel_config = definition.config.parallel.as_ref().unwrap();
    assert!(parallel_config.enabled);
    assert_eq!(parallel_config.max_workers, 2);

    // 验证步骤配置
    assert_eq!(definition.teststeps.len(), 4);

    // 验证条件执行步骤
    let conditional_step = &definition.teststeps[0];
    assert_eq!(conditional_step.if_condition, Some("${enabled}".to_string()));

    // 验证跳过步骤
    let skip_step = &definition.teststeps[1];
    assert_eq!(skip_step.skip, Some(true));

    // 验证重试配置
    let retry_step = &definition.teststeps[2];
    assert!(retry_step.retry.is_some());
    let retry_config = retry_step.retry.as_ref().unwrap();
    assert_eq!(retry_config.max_attempts, 3);
    assert_eq!(retry_config.delay_ms, 1000);
    assert_eq!(retry_config.multiplier, 2.0);

    // 验证循环配置
    let loop_step = &definition.teststeps[3];
    assert!(loop_step.loop_config.is_some());
    let loop_config = loop_step.loop_config.as_ref().unwrap();
    assert_eq!(loop_config.max_iterations, 10);
    assert!(loop_config.data.is_some());
    assert_eq!(loop_config.variable, Some("item".to_string()));

    // 测试参数化扩展
    let expanded_cases = parser.expand_parameterized(&definition).expect("参数化扩展失败");
    assert_eq!(expanded_cases.len(), 2);

    // 验证第一个参数化用例
    let first_case = &expanded_cases[0];
    assert_eq!(first_case.config.name, "增强DSL功能测试_param_0");
    let first_vars = first_case.config.variables.as_ref().unwrap();
    assert_eq!(first_vars.get("user_type").unwrap().as_str().unwrap(), "admin");

    // 验证第二个参数化用例
    let second_case = &expanded_cases[1];
    assert_eq!(second_case.config.name, "增强DSL功能测试_param_1");
    let second_vars = second_case.config.variables.as_ref().unwrap();
    assert_eq!(second_vars.get("user_type").unwrap().as_str().unwrap(), "user");

    // 测试条件评估
    let mut test_vars = std::collections::HashMap::new();
    test_vars.insert("enabled".to_string(), serde_json::Value::Bool(true));
    test_vars.insert("user_type".to_string(), serde_json::Value::String("admin".to_string()));

    // 测试布尔条件
    assert!(parser.evaluate_condition("${enabled}", &test_vars).unwrap());

    // 测试字符串相等条件
    assert!(parser.evaluate_condition("${user_type} == \"admin\"", &test_vars).unwrap());
    assert!(!parser.evaluate_condition("${user_type} == \"user\"", &test_vars).unwrap());

    // 测试步骤跳过逻辑
    assert!(parser.should_skip_step(&skip_step, &test_vars).unwrap());
    assert!(!parser.should_skip_step(&conditional_step, &test_vars).unwrap());

    println!("✅ 增强DSL功能测试通过！");
}
